package com.mianyang.zhangsan.auth.filter;

import com.mianyang.zhangsan.auth.config.RsaKeyProperties;
import com.mianyang.zhangsan.common.constant.SecConstant;
import com.mianyang.zhangsan.common.util.CacheHelper;
import com.mianyang.zhangsan.common.util.JwtUtils;
import com.mianyang.zhangsan.common.util.Payload;
import com.mianyang.zhangsan.common.util.StringUtils;
import com.mianyang.zhangsan.model.entity.AccountDetail;
import com.mianyang.zhangsan.model.entity.SecAccount;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author jiangjr
 * @date 2022-10-23
 */
@Slf4j
@Component
public class TokenVerifyFilter extends OncePerRequestFilter {
    @Autowired
    private RsaKeyProperties properties;
    @Autowired
    private CacheHelper cacheHelper;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        // 如果没有携带token，返回提示信息
        if (StringUtils.isEmpty(token)) {
            filterChain.doFilter(request, response);
            return;
        }
        // 校验token是否正确
        Payload<AccountDetail> payload;
        try {
            payload = JwtUtils.getInfoFromToken(token, properties.getPublicKey(),
                    AccountDetail.class);
        } catch (Exception e) {
            log.error("令牌过期");
            throw new RuntimeException("令牌过期");
        }
        AccountDetail accountDetail = payload.getUserInfo();
        if (accountDetail != null) {
            SecAccount account = accountDetail.getAccount();
            //  token验证
            String key = SecConstant.SEC_KEEP_LIVE_KEY + account.getAccountId();
            Object cacheAccount = cacheHelper.getValue(key);
            if (cacheAccount instanceof AccountDetail) {
                if (accountDetail.equals(cacheAccount)) {
                    // 当前用户token超时设置
                    log.info("当前token超时时间剩余：{}", cacheHelper.getExpire(key));
                    log.info("最小活跃时间：{}", SecConstant.SEC_KEEP_LIVE);
                    if (cacheHelper.getExpire(key) <= SecConstant.SEC_KEEP_LIVE) {
                        log.info("set set...");
                        cacheHelper.setExpire(key, SecConstant.SEC_LOGIN_EXPIRE);
                    }
                    request.setAttribute("accountName", account.getAccountName());
                    request.setAttribute("accountId", account.getAccountId());
                    // 将认证信息存储到上下文变量中
                    UsernamePasswordAuthenticationToken authenticationToken =
                            new UsernamePasswordAuthenticationToken(account, null, accountDetail.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                    filterChain.doFilter(request, response);
                }
            }
        }
    }
}
